#include <string>
#include <iostream>

#include <termios.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

using namespace std;

#define max(a,b) ((a) > (b) ? (a) : (b))

//reads a single char from stdin and emits its scan code.

int getch() {
	struct
	termios oldt,newt;
	int ch;
	tcgetattr( STDIN_FILENO, &oldt );
	newt = oldt;
	newt.c_lflag &= ~( ICANON | ECHO );
	tcsetattr( STDIN_FILENO, TCSANOW, &newt );
	ch = getchar();
	tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
	return ch;
}

void eraseTerminal(int numOfBytes) {
	for (int i=0;i<numOfBytes;++i)
		cout << '\b'<< ' ' << (char)27 << (char)91 << (char)68;
}

void moveRight(int count) {
	for (int i=0;i<count;++i)
		cout << (char)27 << (char)91 << (char)67;
}

//Reads characters from stream and stores them as a C string into buff until a newline is reached or
// TAB / up arrow / down arrow is clicked, whichever comes first.

int getLine(char* buff) {
	int count = strlen(buff);
	int maxCount = count;
	char c;
	cin.clear();
	cout.clear();
	if (strlen(buff) > 0)
		cout << buff;
	while((c = getch()) != 10) {
		//cout << "count  " << count << " chr: "<<(int)c << endl;
		if (c == 9) { //TAB
			buff[maxCount] = '\0';
			cout << endl;
			return 1;
		}
		else if (c == 127) {
			if (count > 0) { //backSpace
				eraseTerminal(1);
				if (maxCount == count) {
					--maxCount;
					buff[count--] = '\0';
				}
				else
					buff[count--] = ' ';
			}
			else {/*supress keypress*/}
		}
		else if (c == 27 && getch() == 91) { //arrows
			int next = getch();
			if (next == 65) { //up click
				moveRight(maxCount-count);
				eraseTerminal(maxCount);
				return -2;
			}
			if (next == 66) { //down click
				moveRight(maxCount-count);
				eraseTerminal(maxCount);
				return -1;
			}
			if (next == 67 && count < maxCount) { //right click
				moveRight(1);
				++count;
			}
			else if (next == 68 && count > 0) { //left click
				cout << (char)27 << (char)91 << (char)68;
				--count;
			}
		}
		else if (c < 30) {} //let hope no shit will slip.
		else {
			cout << c;
			buff[count++] = c;
			maxCount = max(maxCount,count);
		}
	}
	buff[maxCount] = '\0'; //make it a string
	cout << endl;
	return 0;
}
